home *** CD-ROM | disk | FTP | other *** search
- .XLIST
- PAGE 60,132
- TITLE BITBLT-BIT BLOCK XFER FOR IBM PC VERSION 1.0 BY T. PISEK---
- .LIST
- BITBLT PROC FAR
- ?BITBLT SEGMENT WORD PUBLIC 'CODE'
- ASSUME CS:?BITBLT,DS:?BITBLT
- JMP BITBLT_MAIN
- ;*********************************************************************
- ; *
- ; *
- ; *
- ; *
- ; *
- ; *
- ; *
- ; BBBBBBB IIIIIIII TTTTTTTTTT BBBBBBB LL TTTTTTTTTT *
- ; B B II TT B B LL TT *
- ; B B II TT B B LL TT *
- ; BBBBBBB II TT BBBBBBB LL TT *
- ; B B II TT B B LL TT *
- ; B B II TT B B LL_____ TT *
- ; BBBBBBB IIIIIIII TT BBBBBBB LLLLLLL TT *
- ; *
- ; *
- ; *
- ; *
- ; *
- ; *
- ; *
- ;*********************************************************************
- ;
- .XLIST
- SUBTTL BITBLT MODE OPERATION PARAMETERS
- .LIST
- PAGE +
- BITS_WORD EQU 16 ;BITS PER WORD
- ;*********************************************************************
- ; *
- ; THE FOLLOWING ARE SET ON INITALIZATION CALL TO BITBLT *
- ; *
- ;*********************************************************************
- ;
- PIXELS_WORD DW 8 ;NUMBER OF PIXELS/WORD
- LOG_PIX_WRD DW 3 ;LOG OF ABOVE
- BITS_PIXEL DW 2 ;BITS PER PIXEL
- LOG_BITS_PIX DW 1 ;LOG OF ABOVE
- MODULO_PIX DW 3 ;NUMBER OF BITS TO RETAIN FOR MOD
- VIDEO_SEG DW 0 ;SEGMENT VAL OF VIDEO MEMORY
- CAN_VIDEO DW 0 ;CAN WE WRITE INTO VIDEO
- DISPLAY_PROC DD 0 ;IF NOT WHO WILL
- .XLIST
- SUBTTL STRUCTURE DEFINITIONS
- .LIST
- PAGE +
- ;
- ; THE POINT STRUCTURE
- ;
- P STRUC
- X DW ? ; X COORDINATE
- Y DW ? ; Y COORDINATE
- P ENDS
- ;
- ; THE RECTANGLE STRUCTURE
- ;
- RECT STRUC
- O_X DW ? ; UPPER LEFT X COOR
- O_Y DW ? ; UPPER LEFT Y COOR
- C_X DW ? ; LOWER RIGHT X COOR
- C_Y DW ? ; LOWER RIGHT Y COOR
- RECT ENDS
- ;
- ; THE BITMAP STRUCTURE
- ;
- BITMAP STRUC
- BASE DD ? ; POINTER TO BITMAP DATA
- BM_WIDTH DW ? ; WIDTH OF DATA IN WORDS
- BM_O_X DW ? ; RECTANGLE DEFINING DATA AREA
- BM_O_Y DW ? ; RECTANGLE DEFINING DATA AREA
- BM_C_X DW ? ; RECTANGLE DEFINING DATA AREA
- BM_C_Y DW ? ; RECTANGLE DEFINING DATA AREA
- BM_OBS DD ? ; POINTER TO OBSCURED NODE
- BM_ENDOBS DD ? ; POINTER TO LAST OBSCURED NODE
- BITMAP ENDS
- ;
- ; PARAMETERS PASSED FROM 'C' ROUTINES
- ;
- PARMS STRUC
- DUMMY_PARM1 DD ?
- DUMMY_PARM2 DW ?
- SOURCE_PARM DD ? ;POINTER TO SOURCE BITMAP
- RECT_PARM DD ? ;POINTER TO RECTANGLE DEFINING COPY
- DEST_PARM DD ? ;POINTER TO DESTINATION BITMAP
- POINT_PARM DD ? ;POINTER TO POINT TO START IN DEST
- HTONE_PARM DD ? ;POINTER TO HALFTONE BITMAP
- FUNCT_PARM DW ? ;FUNCTION TO PERFORM (BITBLT OP CODE)
- PARMS ENDS
- .XLIST
- SUBTTL BITBLT OPERATION CODE DEFINITIONS
- .LIST
- PAGE +
- ;
- ;*********************************************************************
- ; *
- ; EQUATES FOR BITBLT OPERATION CODES *
- ; *
- ; *
- ; *
- ;*********************************************************************
- ;
- OP_ZERO EQU 0
- OP_SANDD EQU 1
- OP_SANDND EQU 2
- OP_S EQU 3
- OP_NSANDD EQU 4
- OP_D EQU 5
- OP_SXORD EQU 6
- OP_SORD EQU 7
- OP_NSANDND EQU 8
- OP_NSXORD EQU 9
- OP_ND EQU 10
- OP_SORND EQU 11
- OP_NS EQU 12
- OP_NSORD EQU 13
- OP_NSORND EQU 14
- OP_ONES EQU 15
- .XLIST
- SUBTTL CODE TEMPLATES----ROTATE CODES
- .LIST
- PAGE +
- ;
- ;*********************************************************************
- ; *
- ; THE FOLLOWING ARE CODE TEMPLATES USED TO MODIFY THE *
- ; UGLY HORIZONTAL LOOP CODE. *
- ; *
- ;*********************************************************************
- ;
- ;*********************************************************************
- ; *
- ; THE FOLLOWING TABLE IS USED TO DYNAMICALLY ALTER THE *
- ; ROTATE CODE IN THE UGLY HORIZONTAL COPY CODE. *
- ; ROTATE_LEFT[SHIFT_COUNT] YIELDS THE STARTING ADDRESS OF THE *
- ; STREAM OF INSTRUCTIONS TO COPY INTO THE HORZ. CODE *
- ; NOTE THAT THE MOVE IS USED INSTEAD OF NOP BECAUSE NOP TAKES *
- ; 3 CLOCKS TO EXECUTE, MOV ONLY 2 CLOCKS *
- ; *
- ; THE MAXIMUM ROTATE COUNT IS 16 BITS.................BUT THE *
- ;CODE WHICH WRITES TO ROTATE STREAMS DETECTS ROTATES OVER 8 BITS *
- ;AND REPLACES THEM WITH AN OPPOSITE DIRECTION ROTATE OF 16-COUNT. *
- ; *
- ;*********************************************************************
- ;
- EVEN
- ROTATE_LEFT:
- ROL AX,1 ; INDEX TO HERE FOR 8 BIT ROTATE
- ROL AX,1
- ROL AX,1 ; INDEX HERE FOR 6 BIT ROTATE
- ROL AX,1
- ROL AX,1 ; INDEX HERE FOR 4 BIT ROTATE
- ROL AX,1
- ROL AX,1 ; INDEX HERE FOR 2 BIT ROTATE
- ROL AX,1
- MOV AX,AX ; NEVER INDEX HERE. SPECIAL COPY
- MOV AX,AX ; LOOP FOR ALIGNED WORDS
- MOV AX,AX
- MOV AX,AX
- MOV AX,AX
- EVEN
- ROTATE_RIGHT:
- ROR AX,1 ; INDEX TO HERE FOR 8 BIT ROTATE
- ROR AX,1
- ROR AX,1 ; INDEX HERE FOR 6 BIT ROTATE
- ROR AX,1
- ROR AX,1 ; INDEX HERE FOR 4 BIT ROTATE
- ROR AX,1
- ROR AX,1 ; INDEX HERE FOR 2 BIT ROTATE
- ROR AX,1
- MOV AX,AX ; NEVER INDEX HERE. SPECIAL COPY
- MOV AX,AX ; LOOP FOR ALIGNED WORDS
- MOV AX,AX
- MOV AX,AX
- MOV AX,AX
- .XLIST
- SUBTTL CODE TEMPLATES----DO PRECHARGE CODE
- .LIST
- PAGE +
- ;
- ;*********************************************************************
- ; *
- ; THE FOLLOWING TABLE IS USED TO DYNAMICALLY ALTER THE *
- ; LEAD INTO THE SECOND WORD FETCH OF THE HORIZ COPY CODE. *
- ; *
- ; IF 2 SOURCE WORDS ARE NEEDED TO WRITE THE FIRST DESTINATION *
- ; WORD, THE SECOND WORD NEEDS TO BE FETCHED AND ROTATED, THEN *
- ; MERGED WITH THE FIRST WORD. IF THE SECOND WORD IS NOT NEEDED, *
- ; THEN A SHORT JUMP IS WRITTEN OVER THE LODSW AND THE OPCODE *
- ; FOR THE FIRST ROTATE INSTRUCTION TO SKIP THE SECOND WORD FETCH *
- ; AND MERGE CODE---THIS IS THE SKIP ENTRY. *
- ; *
- ; IF A PRECHARGE IS NECESSARY, THEN THE LODSW MUST BE WRITTEN *
- ; BACK INTO THE SECOND WORD FETCH AREA (THE ROTATE CODE WILL *
- ; REWRITE THE OFFSET OF THE JUMP IF THE OPCODE FOR THE 1ST *
- ; ROTATE WAS DESTROYED)---THIS IS THE LOAD ENTRY *
- ; *
- ;*********************************************************************
- ;
- LOAD_CODE:
- LODSW
- EVEN
- SKIP DB 0,0 ; WRITE CODE FOR JMP SHORT NO_PRCHRG
- .XLIST
- SUBTTL CODE TEMPLATES----BITBLT OPERATION CODES
- .LIST
- PAGE +
- ;
- ;*********************************************************************
- ; *
- ; THE FOLLOWING TABLE IS INDEXED BY THE OPERATION CODE. IT IS *
- ; USED TO REWRITE THE OPERATION PORTION OF THE HORIZONTAL CODE *
- ; EACH ENTRY IS 8 BYTES LONG (3 SHIFTS LEFT ON INDEX) *
- ; *
- ; WE DO THIS INSTEAD OF A GENERAL ROUTINE (MERGE) TO SAVE *
- ; A LOT OF TIME. *
- ; *
- ; *
- ; THIS TABLE IS FOR FORWARD REFERENCES A DUPLICATE FOLLOWS *
- ; FOR BACKWARD COPYING *
- ;*********************************************************************
- ;
- EVEN
- OPN_LOOP_F EQU $
- CODE_ZERO_F DB 8 DUP(0)
- S_AND_D_F EQU $
- AND ES:[DI],AX
- INC DI
- INC DI
- NOP
- MOV AX,AX
- S_AND_ND_F EQU $
- NOT AX
- OR AX,ES:[DI]
- NOT AX
- STOSW
- S_F EQU $
- STOSW
- NOP
- MOV AX,AX
- MOV AX,AX
- MOV AX,AX
- NS_AND_D_F EQU $
- NOT AX
- AND ES:[DI],AX
- INC DI
- INC DI
- NOP
- D_F EQU $
- DB 8 DUP(0)
- S_XOR_D_F EQU $
- XOR ES:[DI],AX
- INC DI
- INC DI
- MOV AX,AX
- NOP
- PAGE
- S_OR_D_F EQU $
- OR ES:[DI],AX
- INC DI
- INC DI
- NOP
- MOV AX,AX
- NS_AND_ND_F EQU $
- OR AX,ES:[DI]
- NOT AX
- STOSW
- MOV AX,AX
- NS_XOR_D_F EQU $
- NOT AX
- XOR ES:[DI],AX
- INC DI
- INC DI
- NOP
- ND_F EQU $
- DB 8 DUP(0)
- S_OR_ND_F EQU $
- NOT AX
- AND AX,ES:[DI]
- NOT AX
- STOSW
- NS_F EQU $
- NOT AX
- STOSW
- NOP
- MOV AX,AX
- MOV AX,AX
- NS_OR_D_F EQU $
- NOT AX
- OR ES:[DI],AX
- INC DI
- INC DI
- NOP
- NS_OR_ND_F EQU $
- AND ES:[DI],AX
- NOT AX
- STOSW
- MOV AX,AX
- CODE_ONES_F EQU $
- DB 8 DUP(0)
- PAGE
- ;
- ;*********************************************************************
- ; *
- ; THE FOLLOWING TABLE IS INDEXED BY THE OPERATION CODE. IT IS *
- ; USED TO REWRITE THE OPERATION PORTION OF THE HORIZONTAL CODE *
- ; EACH EHTRY IS 8 BYTES LONG (3 SHIFTS LEFT ON INDEX) *
- ; *
- ; THIS TABLE IS FOR COPYING BACKWARDS *
- ; *
- ;*********************************************************************
- ;
- EVEN
- OPN_LOOP_B EQU $
- CODE_ZERO_B DB 8 DUP(0)
- S_AND_D_B EQU $
- AND ES:[DI],AX
- DEC DI
- DEC DI
- NOP
- MOV AX,AX
- S_AND_ND_B EQU $
- NOT AX
- OR AX,ES:[DI]
- NOT AX
- STOSW
- S_B EQU $
- STOSW
- NOP
- MOV AX,AX
- MOV AX,AX
- MOV AX,AX
- NS_AND_D_B EQU $
- NOT AX
- AND ES:[DI],AX
- DEC DI
- DEC DI
- NOP
- D_B EQU $
- DB 8 DUP(0)
- S_XOR_D_B EQU $
- XOR ES:[DI],AX
- DEC DI
- DEC DI
- MOV AX,AX
- NOP
- PAGE
- S_OR_D_B EQU $
- OR ES:[DI],AX
- DEC DI
- DEC DI
- NOP
- MOV AX,AX
- NS_AND_ND_B EQU $
- OR AX,ES:[DI]
- NOT AX
- STOSW
- MOV AX,AX
- NS_XOR_D_B EQU $
- NOT AX
- XOR ES:[DI],AX
- DEC DI
- DEC DI
- NOP
- ND_B EQU $
- DB 8 DUP(0)
- S_OR_ND_B EQU $
- NOT AX
- AND AX,ES:[DI]
- NOT AX
- STOSW
- NS_B EQU $
- NOT AX
- STOSW
- NOP
- MOV AX,AX
- MOV AX,AX
- NS_OR_D_B EQU $
- NOT AX
- OR ES:[DI],AX
- DEC DI
- DEC DI
- NOP
- NS_OR_ND_B EQU $
- AND ES:[DI],AX
- NOT AX
- STOSW
- MOV AX,AX
- CODE_ONES_B EQU $
- DB 8 DUP(0)
- PAGE
- ;
- ;*********************************************************************
- ; *
- ; THE FOLLOWING TABLE IS INDEXED BY THE OPERATION CODE. IT IS *
- ; USED TO REWRITE THE OPERATION PORTION OF THE HORIZONTAL PROLOG *
- ; AND EPILOG ASSUMES SOURCE IN BX, DESTINATION IN AX EACH ENTRY *
- ; 8 BYTES AS BEFORE (ONLY FIRST 6 USED) *
- ;*********************************************************************
- ;
- EVEN
- OPN_PRO_EPI EQU $
- CODE_ZERO EQU $ ; ALL ZEROS (DONE IN SPECIAL CODE)
- DB 8 DUP(0)
- S_AND_D EQU $
- AND AX,BX
- MOV AX,AX
- MOV AX,AX
- MOV AX,AX
- S_AND_ND EQU $
- NOT AX
- AND AX,BX
- MOV AX,AX
- MOV AX,AX
- S EQU $
- MOV AX,BX
- MOV AX,AX
- MOV AX,AX
- MOV AX,AX
- NS_AND_D EQU $
- NOT BX
- AND AX,BX
- MOV AX,AX
- MOV AX,AX
- D EQU $
- DB 8 DUP(0)
- PAGE
- S_XOR_D EQU $
- XOR AX,BX
- MOV AX,AX
- MOV AX,AX
- MOV AX,AX
- S_OR_D EQU $
- OR AX,BX
- MOV AX,AX
- MOV AX,AX
- MOV AX,AX
- NS_AND_ND EQU $
- OR AX,BX
- NOT AX
- MOV AX,AX
- MOV AX,AX
- NS_XOR_D EQU $
- NOT BX
- XOR AX,BX
- MOV AX,AX
- MOV AX,AX
- ND EQU $
- DB 8 DUP(0)
- S_OR_ND EQU $
- NOT AX
- OR AX,BX
- MOV AX,AX
- MOV AX,AX
- NS EQU $
- NOT BX
- MOV AX,BX
- MOV AX,AX
- MOV AX,AX
- NS_OR_D EQU $
- NOT BX
- OR AX,BX
- MOV AX,AX
- MOV AX,AX
- NS_OR_ND EQU $
- AND AX,BX
- NOT AX
- MOV AX,AX
- MOV AX,AX
- CODE_ONES EQU $
- DB 8 DUP(0)
- .XLIST
- SUBTTL MERGE MASKS
- .LIST
- PAGE +
- ;
- ;*********************************************************************
- ; *
- ; THE FOLLOWING ARE THE MASKS TO BE USED IN THE ROTATE AND *
- ; MERGE FUNCTIONS OF THE INNER HORZ. COPY CODE *
- ; THIS TABLE ASSUMES 2 BITS PER PIXEL *
- ; *
- ; NEED TO USE BYTE TO MATCH *
- ; THE WAY THE PIXELS ARE LOADED INTO *
- ; A REGISTER FROM MEMORY IE *
- ; 0 1 2 3 4 5 6 7 IN ONE WORD OF MEM *
- ; 4 5 6 7 0 1 2 3 IS THIS IN REG *
- ;*********************************************************************
- ;
- EVEN
- MASKS DB 00H,00H ;
- DB 00H,01H ;
- DB 00H,03H ;
- DB 00H,07H ;
- DB 00H,0FH ;
- DB 00H,1FH ;
- DB 00H,3FH ;
- DB 00H,7FH ;
- DB 00H,0FFH ;
- DB 01H,0FFH ;
- DB 03H,0FFH ;
- DB 07H,0FFH ;
- DB 0FH,0FFH ;
- DB 1FH,0FFH ;
- DB 3FH,0FFH ;
- DB 7FH,0FFH ;
- BACK_MASKS DB 0FFH,0FFH ;
- DB 7FH,0FFH ;
- DB 3FH,0FFH ;
- DB 1FH,0FFH ;
- DB 0FH,0FFH ;
- DB 07H,0FFH ;
- DB 03H,0FFH ;
- DB 01H,0FFH ;
- DB 00H,0FFH ;
- DB 00H,7FH ;
- DB 00H,3FH ;
- DB 00H,1FH ;
- DB 00H,0FH ;
- DB 00H,07H ;
- DB 00H,03H ;
- DB 00H,01H ;
- DB 00H,00H ;
- .XLIST
- SUBTTL MASK GET PROCEDURES
- .LIST
- PAGE +
- GET_MASK PROC NEAR
- PUSH BX ;SAVE BX,CX
- PUSH CX
- XOR CX,CX ;CLEAR CX
- MOV CX,BITS_PIXEL ;GET BITS PER PIXEL
- INC CX ;MASKS ARE WORDS
- SAL BX,CL ;MULT INDEX BY (BITS_PIXEL+1)*2
- MOV AX,WORD PTR MASKS[BX] ;GET MASK
- POP CX ;RESTORE REGS
- POP BX
- RET
- GET_MASK ENDP
- ;
- ;
- ;
- GET_BMASK PROC NEAR
- PUSH BX ;SAVE BX,CX
- PUSH CX
- XOR CX,CX ;CLEAR CX
- MOV CX,BITS_PIXEL ;GET BITS PER PIXEL
- INC CX ;MASKS ARE WORDS
- SAL BX,CL ;MULT INDEX BY (BITS_PIXEL+1)*2
- MOV AX,WORD PTR BACK_MASKS[BX] ;GET MASK
- POP CX ;RESTORE REGS
- POP BX
- RET
- GET_BMASK ENDP
- .XLIST
- SUBTTL STATIC STORAGE AREAS
- .LIST
- PAGE +
- EVEN
- ;
- ; PARAMETERS PASSED
- ;
- OPN_CODE DB 0 ; BITBLT OPERATION CODE (0-16)
- DB 0 ; ALIGN TO WORD BOUNDRY
- SOURCE_PTR DD 0 ; POINTER TO SOURCE BITMAP
- DEST_PTR DD 0 ; POINTER TO DESTINATION BITMAP
- SAVE_PTR DD 0 ; IF CAN'T COPY TO VIDEO, SAVE OLD
- HTONE_PTR DD 0 ; POINTER TO HALFTONE/COLOR BITMAP
- RECT_PTR DD 0 ; POINTER TO CLIPPING RECTANGLE
- POINT_PTR DD 0 ; POINTER TO POINT IN DEST TO START
- ;
- ; INTERNAL VARIABLES
- ;
- S_X DW 0 ; SOURCE X COOR
- S_Y DW 0 ; SOURCE Y COOR
- SOURCE_INDX DW 0 ; OFFSET INTO SOURCE FOR COPY
- DEST_INDX DW 0 ; OFFSET INTO DESTINATION FOR COPY
- D_X DW 0 ; DESTINATION X COOR
- D_Y DW 0 ; DESTINATION Y COOR
- DIRECTION DW 0 ; LEFT OR RIGHT ROTATE
- COUNT DW 0 ; ROTATE COUNT IN BITS
- SSKEW_RIGHT DW 0 ; NUMBER OF PIXELS OFF ON RIGHT
- SSKEW_LEFT DW 0 ; NUMBER OF PIXELS OFF ON LEFT
- DSKEW_RIGHT DW 0 ; NUMBER OF PIXELS OFF ON RIGHT
- DSKEW_LEFT DW 0 ; NUMBER OF PIXELS OFF ON LEFTT
- PRECHRG DW 0 ; IF 1 THEN USE PRECHARGE CODE
- NO_PREC EQU 0
- VDIR DW 0 ; IF 1 THEN BACKWARD VERT COPY
- FORWARD EQU 0
- HDIR DW 0 ; IF 1 THEN BACKWARD HORZ COPY
- WIDTH_PIX DW 0 ; WIDTH OF RECTANGLE CLIP IN PIXELS
- HEIGHT_PIX DW 0 ; HEIGHT OF RECTANGLE CLIP IN PIXELS
- NWORDS DW 0 ; NUMBER OF WORDS FOR HORZ COPY
- MAX_VECTOR EQU 64
- V_WORD_CNT DW 0 ; NUMBER OF HORZ SCANS
- DELTA_S DW 0 ; AMOUNT TO GET TO NEXT LINE
- DELTA_D DW 0 ; AMOUNT TO GET TO NEXT LINE
- ALIGN_PRMASK DW 0 ; PROLOGUE MASK FOR ALIGNED COPY
- ALIGN_EPMASK DW 0 ; EPILOGUE MASK FOR ALIGNED COPY
- CURR_PTR_S DD 0 ; POINTER TO 1ST WORD OF CURRENT LINE
- CURR_PTR_D DD 0 ; POINTER TO 1ST WORD OF CURRENT LINE
- HTONE_INDX DB 0 ; INDEX INTO HTONE_VEC (BYTE)
- HTONE_MOD DB 0 ; NUMBER OF BITS TO RETAIN FOR MODULO
- HTONE_VEC DW MAX_VECTOR DUP(0) ; VECTOR OF HALFTONE WORDS
- DS_SAVE DW ? ; SAVE AREA FOR DS
- ES_SAVE DW ? ; SAVE AREA FOR ES
- SAVE_SS DW ? ; SAVE AREA FOR SS
- SAVE_SP DW ? ; SAVE AREA FOR SP
- BP_SAVE DW ? ; SAVE AREA FOR BP
- .XLIST
- SUBTTL BITBLT ENTRY POINT CODE
- .LIST
- PAGE +
- EVEN
- BITBLT_MAIN:
- ;*********************************************************************
- ; *
- ; BITBLT MAIN ENTRY POINT *
- ;
- ;*********************************************************************
- ;
- ;
- ; GET PARAMETERS FROM 'C' CALLING ROUTINE AND VERIFY PARMS
- ;
- CALL C_INTFACE
- JC BITBLT_EXIT1 ; IF ERROR, EXIT
- ;
- ; CLIP TO SMALLEST RECTANGLE
- ;
- CALL CLIP_RECT
- JC BITBLT_EXIT1 ; IF ERROR, EXIT
- ;
- ; COMPUTE THE SOURCE AND DESTINATION SKEWS
- ;
- CALL CALC_SKEWS
- ;
- ; CHECK FOR SOURCE DESTINATION OVERLAP
- ;
- CALL CHK_OVLAP
- ;
- ; CALCULATE NUMBER OF WORDS PER HORIZONTAL SCAN
- ;
- CALL CALC_NWORD
- ;
- ; CALCULATE STARTING OFFSETS
- ;
- CALL CALC_START
- ;
- ; CALCULATE AMOUNT TO ADD TO GET TO NEXT SCAN LINE
- ;
- CALL CALC_DELTA
- ;
- ; BUILD HALFTONE VECTOR AND INDEX FROM HALFTONE POINTER
- ;
- CALL HTONE_GET
- PAGE
- ;
- ; IF BITBLT CODE IS D OR NOT D THEN DO FAST VERSION
- ;
- MOV AL,OPN_CODE
- CMP AL,OP_D ; OP CODE OF D
- JE FAST_COPY
- CMP AL,OP_ND ; OP CODE OF ~D
- JE FAST_COPY
- CMP AL,OP_ZERO
- JE FAST_COPY
- CMP AL,OP_ONES
- JE FAST_COPY
- ;
- ; IF HERE THEN NOT SIMPLE CODE
- ;
- ;
- ; CHECK IF SOURCE AND DEST ARE ALIGNED
- ; IF THEY ARE THEN DO FAST VERSION
- ;
- MOV AX,SSKEW_LEFT
- CMP AX,DSKEW_LEFT
- JE ALIGN_COPY
- CALL COPY_NALIGN
- JMP SHORT BITBLT_EXIT
- ALIGN_COPY:
- CALL COPY_ALIGN
- JMP SHORT BITBLT_EXIT
- FAST_COPY:
- CALL FAST_COPY
- BITBLT_EXIT:
- ;
- ; IF BITBLT DIDN'T DO ITS THING TO THE DISPLAY, COPY THE DEST BITMAP
- ; TO THE VIDEO USING THE PROCEDURE PROVIDED AT INITALIZATION
- ;
- CALL COPY_DISPLAY
- BITBLT_EXIT1:
- ;
- ; CLEANUP REGS AND RET
- ;
- MOV SS,SAVE_SS ; RESTORE SS
- MOV BP,BP_SAVE ; RESTORE BP
- MOV DS,CS:DS_SAVE ; RESTORE DS
- MOV SP,BP ; RESTORE SP
- POP BP ; RESTORE BP
- RET
- .XLIST
- SUBTTL INTERFACE TO 'C' ROUTINES AND ERROR CHECK
- .LIST
- PAGE +
- C_INTFACE PROC NEAR
- ;*********************************************************************
- ; *
- ; GET PARAMETERS FROM STACK AND VERIFY *
- ; *
- ;*********************************************************************
- ;
- PUSH BP ; SAVE BP
- MOV BP,SP
- MOV DI,OFFSET SOURCE_PTR ;SET DI TO INTERNAL PARMS
- LES SI,[BP].SOURCE_PARM
- MOV CS:[DI],SI ; SAVE SOURCE BITMAP PTR
- INC DI
- INC DI
- MOV CS:[DI],ES
- INC DI
- INC DI
- LES SI,[BP].DEST_PARM
- MOV CS:[DI],SI ; SAVE DEST BITMAP PTR
- INC DI
- INC DI
- MOV CS:[DI],ES
- INC DI
- INC DI
- LES SI,[BP].HTONE_PARM
- MOV CS:[DI],SI ; SAVE HALFTONE BITMAP PTR
- INC DI
- INC DI
- MOV CS:[DI],ES
- INC DI
- INC DI
- LES SI,[BP].RECT_PARM
- MOV CS:[DI],SI ; SAVE RECTANGLE POINTER
- INC DI
- INC DI
- MOV CS:[DI],ES
- INC DI
- INC DI
- LES SI,[BP].POINT_PARM
- MOV CS:[DI],SI ; SAVE POINT POINTER
- INC DI
- INC DI
- MOV CS:[DI],ES
- MOV AX,[BP].FUNCT_PARM ; SAVE BITBLT OPCODE
- MOV WORD PTR CS:OPN_CODE,AX
- MOV CS:DS_SAVE,DS ;GET DS TO CODE SEG
- MOV AX,CS
- MOV DS,AX
- MOV SAVE_SS,SS
- MOV BP_SAVE,BP
- PAGE
- ;
- ; NOW VERIFY THE PARMS
- ;
- LES SI,SOURCE_PTR
- MOV AX,ES
- OR AX,SI
- JNZ SOURCE_OK ;IF SOURCE =0
- MOV AL,OPN_CODE ; IS OP CODE = ALL ZEROES?
- CMP AL,OP_ZERO
- JE SOURCE_OK ; YES, OK
- CMP AL,OP_ONES ; OP CODE = ALL ONES?
- JE SOURCE_OK ; YES, OK
- CMP AL,OP_D ; OP CODE = D
- JE SOURCE_OK ; YES, OK
- CMP AL,OP_ND ; OP CODE = ~D
- JNE BAD_PARM ; INVALID SOURCE PARM RESTORE AND RET
- SOURCE_OK:
- LES SI,DEST_PTR ; CHECK FOR NULL DESTINATION
- MOV AX,ES
- OR AX,SI
- JZ BAD_PARM
- DEST_OK:
- LES SI,RECT_PTR ; CHECK FOR NULL RECTANGLE PTR
- MOV AX,ES
- OR AX,SI
- JZ BAD_PARM
- RECT_OK:
- LES SI,POINT_PTR ; CHECK FOR NULL POINT PTR
- MOV AX,ES
- OR AX,SI
- JZ BAD_PARM
- POINT_OK:
- ;
- ; ALL PARMS OK, CLEAR CARRY AND RETURN
- ;
- CLC
- RET
- BAD_PARM:
- ;
- ; BAD PARAMETER. SET CARRY AND RETURN
- ;
- STC
- RET
- C_INTFACE ENDP
- .XLIST
- SUBTTL CLIP TO DEFINING RECTANGLE ROUTINE
- .LIST
- PAGE +
- CLIP_RECT PROC NEAR
- ;
- ;*********************************************************************
- ; *
- ; CLIP CLIPS THE BITBLT OPERATION TO AVOID COPYING BEYOND THE *
- ; BOUNDS OF THE DESTINATION BITMAP *
- ; *
- ;*********************************************************************
- ;
- ; COMPUTE WIDTH IN PIXELS
- ;
- LES SI,RECT_PTR
- MOV AX,ES:[SI].O_X
- MOV S_X,AX
- MOV BX,ES:[SI].C_X
- SUB AX,BX
- MOV CX,AX
- MOV WIDTH_PIX,AX
- ;
- ; COMPUTE HEIGHT IN PIXELS
- ;
- MOV AX,ES:[SI].O_Y
- MOV S_Y,AX
- MOV BX,ES:[SI].C_Y
- SUB AX,BX
- MOV HEIGHT_PIX,AX
- ;
- ; IF WIDTH OR HEIGHT <=0 THEN EXIT
- ;
- XOR DX,DX
- CMP AX,DX
- JLE CLIP_FEXIT
- CMP CX,DX
- JLE CLIP_FEXIT
- PAGE
- ;
- ; VALID H AND W, NOW MAKE SURE WE DO NOT GO BEYOND DESTINATION LIMIT
- ;
- ; FIRST CHECK WIDTH, IE IF P.X+WIDTH>DEST C_X
- ;
- LES SI,DEST_PTR
- MOV DX,AX ; SAVE HEIGHT
- MOV AX,ES:[SI].C_X
- LES DI,POINT_PTR
- MOV BX,ES:[DI].X
- MOV D_X,BX
- ADD BX,CX ; ADD X TO WIDTH
- CMP BX,AX
- JLE CHECK_H
- SUB AX,D_X
- MOV WIDTH_PIX,AX ; CORRECT WIDTH
- CHECK_H:
- ;
- ; NOW CHECK HEIGHT OF COPY
- ;
- MOV AX,ES:[SI].C_Y
- MOV BX,ES:[DI].Y
- ADD BX,DX
- CMP BX,AX
- JLE CLIP_EXIT
- SUB AX,ES:[DI].Y
- MOV HEIGHT_PIX,AX ; CORRECT HEIGHT
- CLIP_EXIT:
- CLC ; CLEAR CARRY CONTINUE
- RET
- CLIP_FEXIT:
- STC ; SET CARRY EXIT BITBLT
- RET
- CLIP_RECT ENDP
- .XLIST
- SUBTTL CALCULATE OFFSET INTO SOURCE AND DESTINATION
- .LIST
- PAGE +
- CALC_START PROC NEAR
- ;
- ;*********************************************************************
- ; *
- ; COMPUTE THE STARTING INDICIES INTO TO SOURCE AND DESTINATION *
- ; *
- ;*********************************************************************
- ; *
- XOR DX,DX
- LES SI,SOURCE_PTR
- CMP SI,DX
- JA CALC_S1
- MOV AX,ES
- CMP AX,DX
- JE CALC_ZERO
- CALC_S1:
- ;
- ; SOURCE NOT NULL, DO FULL CALCULATION
- ;
- ; SOURCEINDEX=((SY-RECT.ORIGIN.Y)*BIT_WIDTH)+(SX/PIXELS_WORD)
- ; - (RECT.ORIGIN.X/PIXELS_WORD)
- MOV CX,ES:[SI].BM_WIDTH
- MOV AX,S_Y
- MOV BX,ES:[SI].BM_O_Y
- SUB AX,BX
- MUL CL
- MOV BX,S_X
- MOV CL,BYTE PTR LOG_PIX_WRD
- MOV CH,CL
- SAR BX,CL
- ADD AX,BX
- MOV BX,ES:[SI].BM_O_X
- MOV CL,CH
- SAR BX,CL
- SUB AX,BX
- MOV SOURCE_INDX,AX
- JMP SHORT SAVE_PTRS
- CALC_ZERO:
- XOR AX,AX
- MOV SOURCE_INDX,AX
- SAVE_PTRS:
- LES SI,ES:[SI].BASE ; GET PTR TO BITMAP DATA
- ADD SI,AX ; ADD OFFSET TO START
- MOV WORD PTR CURR_PTR_S,SI
- MOV WORD PTR CURR_PTR_S+2,ES
- PAGE
- ;
- ; NOW CALC THE START FOR THE DESTINATION
- ;
- ; DESTINDEX=((DY-RECT.ORIGIN.Y)*BIT_WIDTH)+(DX/PIXELS_WORD)
- ; - (RECT.ORIGIN.X/PIXELS_WORD)
- ;
- LES SI,DEST_PTR
- MOV CX,ES:[SI].BM_WIDTH
- MOV AX,D_Y
- MOV BX,ES:[SI].BM_O_Y
- SUB AX,BX
- MUL CL
- MOV BX,D_X
- MOV CL,BYTE PTR LOG_PIX_WRD
- MOV CH,CL
- SAR BX,CL
- ADD AX,BX
- MOV BX,ES:[SI].BM_O_X
- MOV DX,BX
- MOV CL,CH
- SAR BX,CL
- SUB AX,BX
- MOV DEST_INDX,AX
- LES SI,ES:[SI].BASE ; GET PTR TO BITMAP DATA
- ADD SI,AX ; ADD OFFSET TO START
- MOV WORD PTR CURR_PTR_D,SI
- MOV WORD PTR CURR_PTR_D+2,ES
- RET
- CALC_START ENDP
- .XLIST
- SUBTTL CALCULATE SOURCE AND DESTINATION SKEWS
- .LIST
- PAGE +
- CALC_SKEWS PROC NEAR
- ;
- ;*********************************************************************
- ;
- ; COMPUTE LEFT AND RIGHT SKEW FOR SOURCE AND DESTINATION
- ;
- ;*********************************************************************
- ;
- ; SSKEW_LEFT=(BM_O_X+SX) MOD PIXELS_WORD
- ; SSKEW_RIGHT=(BM_O_X+SX+WIDTH_PIX) MOD PIXELS_WORD
- ;
- MOV BP,WORD PTR MODULO_PIX
- LES SI,SOURCE_PTR
- MOV DX,ES:[SI].BM_O_X
- ADD DX,S_X ; BM_O_X+S_X
- MOV AX,DX
- AND AX,BP
- MOV AX,SSKEW_LEFT
- ADD DX,WIDTH_PIX
- AND DX,BP
- MOV SSKEW_RIGHT,DX
- ;
- ; NOW COMPUTE LEFT AND RIGHT SKEW FOR DESTINATION
- ; DSKEW_LEFT=(BM_O_X+DX) MOD PIXELS_WORD
- ; DSKEW_RIGHT=(BM_O_X+DX+WIDTH_PIX) MOD PIXELS_WORD
- ;
- LES SI,DEST_PTR
- MOV DX,ES:[SI].BM_O_X
- ADD DX,D_X ; BM_O_X+S_X
- MOV AX,DX
- AND AX,BP ; MODULO MASK
- MOV AX,DSKEW_LEFT
- ADD DX,WIDTH_PIX
- AND DX,BP
- MOV DSKEW_RIGHT,DX
- RET
- CALC_SKEWS ENDP
- .XLIST
- SUBTTL CHECK FOR OVERLAP CONDITION AND CORRECT
- .LIST
- PAGE +
- CHK_OVLAP PROC NEAR
- ;
- ;*********************************************************************
- ; *
- ; CHECK FOR POSSIBLE OVERLAP IN COPYING INTO ITSELF *
- ; *
- ;*********************************************************************
- ;
- LES SI,SOURCE_PTR
- MOV AX,ES
- LES DI,DEST_PTR
- MOV BX,ES
- CMP AX,BX
- JNE OVLAP_EXIT
- CMP DI,SI
- JNE OVLAP_EXIT
- ;
- ; IF HERE BOTH SOURCE AND DESTINATION BITMAPS ARE THE SAME
- ;
- XOR DX,DX
- MOV HDIR,DX ; IF 0 NORMAL COPY DIRECTION HORZ
- MOV VDIR,DX ; IF 0 NORMAL COPY DIRECTION VERT
- DEC DX ; SET DX FOR BACKWARDS DIRECTION
- ;
- ; CHECK FOR OVERLAP IN VERTICAL DIRECTION
- ;
- MOV AX,D_Y
- MOV BX,S_Y
- CMP AX,BX
- JLE OVLAP_HOR
- ;
- ; GOT OVERLAP IN Y
- ;
- MOV CX,HEIGHT_PIX
- DEC CX
- ADD AX,CX ; D_Y=D_Y+H-1
- ADD BX,CX ; S_Y=S_Y+H-1
- MOV D_Y,AX
- MOV S_Y,BX
- MOV VDIR,DX ; IF 1 THEN BACKWARDS VERT COPYING
- OVLAP_HOR:
- ;
- ; CHECK FOR OVERLAP IN HORIZONTAL DIRECTION
- ;
- MOV AX,D_X
- MOV BX,S_X
- CMP AX,BX
- JLE OVLAP_EXIT
- PAGE
- ;
- ; HORZ COPY BACKWARD
- ;
- MOV CX,WIDTH_PIX
- DEC CX
- ADD AX,CX
- ADD BX,CX
- MOV D_X,AX
- MOV S_X,BX
- MOV HDIR,DX
- ;
- ; SWAP RIGHT AND LEFT SKEW VALUES
- ;
- MOV AX,SSKEW_RIGHT
- MOV BX,SSKEW_LEFT
- XCHG AX,BX
- MOV SSKEW_RIGHT,AX
- MOV SSKEW_LEFT,BX
- ;
- ; NOW DO DESTINATION
- MOV AX,DSKEW_RIGHT
- MOV BX,DSKEW_LEFT
- XCHG AX,BX
- MOV DSKEW_RIGHT,AX
- MOV DSKEW_LEFT,BX
- OVLAP_EXIT:
- RET
- CHK_OVLAP ENDP
- .XLIST
- SUBTTL COMPUTE NUMBER OF WORDS PER HORIZONTAL SCAN
- .LIST
- PAGE +
- CALC_NWORD PROC NEAR
- ;
- ;*********************************************************************
- ; *
- ; CALCULATE THE NUMBER OF WORDS IN A HORIZONTAL COPY *
- ; *
- ;*********************************************************************
- ;
- ; CLEAR PRECHARGE INDICATOR
- ;
- XOR DX,DX
- MOV PRECHRG,DX
- ;
- ; FORM WIDTH MINUS START MINUS 1
- ;
- MOV BX,WIDTH_PIX
- SUB BX,SSKEW_LEFT
- DEC BX
- ;
- ; BX NOW HAS NWORDS IF NO PRECHARGE
- ;
- MOV AX,SSKEW_RIGHT
- CMP AX,DSKEW_RIGHT
- JB NWORD_PRE
- ;
- ; NO PRECHARGE NEEDED
- ;
- MOV NWORDS,BX
- RET
- NWORD_PRE:
- ;
- ; NEED TO PRECHARGE. SET INDICATOR AN DECREMENT NWORD
- ;
- DEC DX
- MOV PRECHRG,DX
- DEC BX
- MOV NWORDS,BX
- RET
- CALC_NWORD ENDP
- .XLIST
- SUBTTL CALCULATE AMOUNT TO GET TO NEXT LINE ROUTINE
- .LIST
- PAGE +
- CALC_DELTA PROC NEAR
- ;
- ;*********************************************************************
- ; *
- ; THIS ROUTINE BUILDS DELTA_S AND DELTA_D. THESE TWO QUANTITIES *
- ; ARE ADDED TO THE ENDING SCAN LINE INDICIES TO GET TO THE START OF *
- ; THE NEXT SCAN LINE *
- ; *
- ; *
- ;*********************************************************************
- ;
- LES SI,SOURCE_PTR
- MOV AX,ES:[SI].BM_WIDTH ;GET WIDTH OF BITMAP
- XOR CX,CX
- CMP CX,VDIR
- JE USE_WIDTH1
- NEG AX ; IF V DIR BACKWARDS THEN
- ; USE -WIDTH
- USE_WIDTH1:
- MOV BX,NWORDS
- CMP CX,PRECHRG
- JNE DONT_INC1 ; IF PRECHARGE ALREADY
- ; ATE SECOND WORD, DONT INC
- INC BX
- DONT_INC1:
- CMP CX,HDIR ; IF H DIR BACKWARD, THEN
- JE USE_NWORDS1 ; USE -NWORDS+(0/1)
- NEG BX
- USE_NWORDS1:
- SUB AX,BX
- MOV DELTA_S,AX
- ;
- ; NOW DO DESTINATION DELTA
- ;
- LES SI,DEST_PTR
- MOV AX,ES:[SI].BM_WIDTH ;GET WIDTH OF BITMAP
- XOR CX,CX
- CMP CX,VDIR
- JE USE_WIDTH2
- NEG AX ; IF V DIR BACKWARDS THEN
- ; USE -WIDTH
- USE_WIDTH2:
- MOV BX,NWORDS
- CMP CX,PRECHRG
- JNE DONT_INC2 ; IF PRECHARGE ALREADY
- ; ATE SECOND WORD, DONT INC
- INC BX
- DONT_INC2:
- CMP CX,HDIR ; IF H DIR BACKWARD, THEN
- JE USE_NWORDS2 ; USE -NWORDS+(0/1)
- NEG BX
- USE_NWORDS2:
- SUB AX,BX
- MOV DELTA_S,AX
- RET
- CALC_DELTA ENDP
- .XLIST
- SUBTTL UNALIGNED HORIZ COPY ROUTINE
- .LIST
- PAGE +
- COPY_NALIGN PROC NEAR
- ;
- ;*********************************************************************
- ; *
- ; PERFORM THE COPYBITS OPERATION FOR NON ALIGNED DATA *
- ; *
- ;*********************************************************************
- ;
- ;*********************************************************************
- ; NOTES ABOUT UNALIGNED COPYING *
- ; *
- ; FOR THE PURPOSES OF ILLUSTRATION, CONSIDER 2 BITS/PIXEL(8 PIX/WORD)*
- ; AND PRECHARGE OPERATION, IE, IT TAKES 2 SOURCE WORDS *
- ; TO GENERATE THE FIRST DESTINATION WORD. *
- ; *
- ; *
- ; SOURCE WORD 1 SOURCE WORD 2 SOURCE WORD 3 *
- ; *-*-*-*-*-*-*-*--RELATIVE--*-*-*-*-*-*-*-*------*-*-*-*-*-*-*-* *
- ; | | | | | | | | PIXEL | | | | | | | | | | | | | | | | *
- ; V V V V V V V V NOS. V V V V V V V V V V V V V V V V *
- ; +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ *
- ; |0|1|2|3|4|5|6|7| |0|1|2|3|4|5|6|7| |0|1|2|3|4|5|6|7| *
- ; +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ *
- ; *
- ; *
- ; 8-RELATIVE PIXEL NOS(LOCAL SKEW) *
- ; *
- ; +----ASSUME SOURCE STARTS HERE *
- ; V *
- ; +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ *
- ; |8|7|6|5|4|3|2|1| |8|7|6|5|4|3|2|1| |8|7|6|5|4|3|2|1| *
- ; +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ *
- ; *
- ; *
- ; SKEW FACTOR IS LOCAL SOURCE SKEW-LOCAL DEST SKEW *
- ; *
- ; +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ *
- ; |8|7|6|5|4|3|2|1| |8|7|6|5|4|3|2|1| *
- ; +-+^+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ *
- ;DESTINATION | *
- ;STARTS HERE------+ DEST WORD 1 DEST WORD 2 *
- ; *
- ; THEN THE SKEW, OR THE NUMBER OF PIXELS WE ARE OFF, IS -4. *
- ; SINCE THE SKEW FACTOR IS NEGATIVE WE MUST DO A PRECHARGE. *
- ; NOTE THAT THE ABSOLUTE VALUE OF THE SKEW FACTOR IS THE *
- ; NUMBER OF PIXELS WE NEED TO SHIFT TO BRING THE SOURCE AND *
- ; DESTINATION INTO ALIGNMENT *
- ; *
- ;*********************************************************************
- ; LEFT ROTATE THE FIRST SOURCE BY SKEW FACTOR *
- ; *
- ; +-+-+-+-+-+-+-+-+ *
- ; |4|3|2|1|8|7|6|5| *
- ; +-+-+-+-+-+-+-+-+ *
- ;*********************************************************************
- PAGE +
- ;*********************************************************************
- ; *
- ; MASK OFF THE PIXELS TO BE USED FROM THE FIRST SOURCE WORD *
- ; *
- ; +-+-+-+-+-+-+-+-+ *
- ; |0|1|1|1|0|0|0|0| MASKS[SOURCE_LOCAL_SKEW] ROTATED BY SKEW FACTOR *
- ; +-+-+-+-+-+-+-+-+ *
- ;*********************************************************************
- ; *
- ; LEFT ROTATE THE SECOND SOURCE WORD BY SKEW FACTOR *
- ; *
- ; +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ *
- ; |0|3|2|1|0|0|0|0| |4|3|2|1|8|7|6|5| |8|7|6|5|4|3|2|1| *
- ; +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ *
- ;*********************************************************************
- ; *
- ; MASK OFF THE PIXELS TO BE USED FROM SOURCE WORD 2 *
- ; *
- ; +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ *
- ; |0|3|2|1|0|0|0|0| |4|3|2|1|8|7|6|5| |8|7|6|5|4|3|2|1| *
- ; +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ *
- ; +-+-+-+-+-+-+-+-+ *
- ; |0|0|0|0|1|1|1|1| MASKS[SKEW_FACTOR] *
- ; +-+-+-+-+-+-+-+-+ *
- ; +-+-+-+-+-+-+-+-+ *
- ; |0|0|0|0|8|7|6|5| *
- ; +-+-+-+-+-+-+-+-+ *
- ;*********************************************************************
- ; *
- ; COMPLEMENT THE MASK AND SAVE THE PIXELS FROM WORD N *
- ; FOR USE WITH N+1 *
- ; *
- ; +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ *
- ; |0|3|2|1|0|0|0|0| |4|3|2|1|8|7|6|5| |8|7|6|5|4|3|2|1| *
- ; +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ *
- ; +-+-+-+-+-+-+-+-+ *
- ; |1|1|1|1|0|0|0|0| NOT MASKS[SKEW_FACTOR]*
- ; +-+-+-+-+-+-+-+-+ *
- ; +-+-+-+-+-+-+-+-+ *
- ; |4|3|2|1|0|0|0|0| SAVE FOR NEXT ROUND *
- ; +-+-+-+-+-+-+-+-+ *
- ;*********************************************************************
- ; *
- ; MERGE SOURCE WORDS 1 AND 2 *
- ; *
- ; +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ *
- ; |0|3|2|1|8|7|6|5| |8|7|6|5|4|3|2|1| *
- ; +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ *
- ;*********************************************************************
- ; *
- ; MASK OFF PIXELS TO BE USED FOROM/TO DESTINATION WORD 1 *
- ; *
- ;DESTINATION *
- ;STARTS HERE------+ DEST WORD 1 DEST WORD 2 *
- ; V *
- ; +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ *
- ; |8|7|6|5|4|3|2|1| |8|7|6|5|4|3|2|1| *
- ; +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ *
- ; +-+-+-+-+-+-+-+-+ *
- ; |0|1|1|1|1|1|1|1| MASKS[DEST_LOCAL_SKEW] *
- ; +-+-+-+-+-+-+-+-+ *
- ; +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ *
- ; |0|7|6|5|4|3|2|1| |8|7|6|5|4|3|2|1| *
- ; +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ *
- ;*********************************************************************
- PAGE +
- ;*********************************************************************
- ; MASK OFF PIXELS NOT USED FOR MERGE BRFORE WRITING DEST WORD 1 *
- ; *
- ;DESTINATION *
- ;STARTS HERE------+ DEST WORD 1 DEST WORD 2 *
- ; V *
- ; +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ *
- ; |8|7|6|5|4|3|2|1| |8|7|6|5|4|3|2|1| *
- ; +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ *
- ; +-+-+-+-+-+-+-+-+ *
- ; |1|0|0|0|0|0|0|0| NOT MASKS[DEST_LOCAL_SKEW] *
- ; +-+-+-+-+-+-+-+-+ *
- ; +-+-+-+-+-+-+-+-+ *
- ; |8|0|0|0|0|0|0|0| SAVE FOR A WHILE *
- ; +-+-+-+-+-+-+-+-+ *
- ;*********************************************************************
- ; *
- ; PERFORM THE BITBLT OPERATION ON THE SOURCE AND DESTINATION USING *
- ; AN OPTIONAL HALFTONE WORD *
- ; *
- ; +-+-+-+-+-+-+-+-+ *
- ; |0|3|2|1|8|7|6|5| SOURCE WORD *
- ; +-+-+-+-+-+-+-+-+ *
- ; +-+-+-+-+-+-+-+-+ *
- ; |H|H|H|H|H|H|H|H| HALF-TONE WORD *
- ; +-+-+-+-+-+-+-+-+ *
- ; +-+-+-+-+-+-+-+-+ *
- ; |0|7|6|5|4|3|2|1| DESTINATION WORD *
- ; +-+-+-+-+-+-+-+-+ *
- ; +-+-+-+-+-+-+-+-+ *
- ; |0|R|R|R|R|R|R|R| RESULT WORD *
- ; +-+-+-+-+-+-+-+-+ *
- ;*********************************************************************
- ; *
- ; MERGE THE PIXELS NOT USED FROM DESTINATION INTO RESULT *
- ; *
- ; +-+-+-+-+-+-+-+-+ *
- ; |8|0|0|0|0|0|0|0| SAVE FOR A WHILE *
- ; +-+-+-+-+-+-+-+-+ *
- ; +-+-+-+-+-+-+-+-+ *
- ; |0|R|R|R|R|R|R|R| RESULT WORD *
- ; +-+-+-+-+-+-+-+-+ *
- ; +-+-+-+-+-+-+-+-+ *
- ; |8|R|R|R|R|R|R|R| STORE TO DESTINATION *
- ; +-+-+-+-+-+-+-+-+ *
- ; *
- ;*********************************************************************
- PAGE +
- ;
- ; FIRST COMPUTE SHIFT DIRECTION AND COUNT
- ;
- ; GET THE SKEW FACTOR
- ;
- XOR BP,BP ; BP WILL DETERMINE LEFT/RIGHT
- XOR DX,DX
- MOV AX,SSKEW_LEFT
- MOV BX,AX
- SUB AX,DSKEW_LEFT
- CMP AX,DX
- JGE DO_SHIFT
- NEG AX
- DEC BP ; NO PRECHARGE, BASE IS LEFT
- DO_SHIFT:
- MOV DI,AX ; USED IF PRECHARGE
- ;
- ; GET DIFFERENCE TIMES BITS PER PIXEL
- ;
- MOV CL,BYTE PTR LOG_BITS_PIX
- SAL AX,CL ; COUNT =(SX-DX)*BITS_PIXEL
- MOV CX,AX
- CMP AL,BYTE PTR BITS_WORD/2
- JNA SHORT SAVE_COUNT
- REVERSE1:
- ;
- ; OPPOSITE DIRECTION COUNT =16-OLD_COUNT
- ;
- MOV CL,BYTE PTR BITS_WORD
- SUB CL,AL
- NOT BP ; CHANGE LEFT TO RIGHT AND VICE VERSA
- SAVE_COUNT:
- MOV COUNT,CX
- TEST HDIR,WORD PTR FORWARD
- JE NORM_DIR
- NOT BP ; IF BACKWARD COPY, REVERSE ROTATE DIR
- NORM_DIR:
- MOV DIRECTION,BP
- ;
- ; NOW BUILD MASKS
- ;
- TEST PRECHRG,WORD PTR NO_PREC
- JNE MASKS_PRECH
- PAGE
- MASKS_NOP:
- ;
- ; BUILD MASKS FOR NON PRECHARGE OPERAION AND STORE THEM INTO
- ; THE COPY ROUTINE
- ;
- TEST HDIR,WORD PTR FORWARD
- JE MASKS_FORW1
- CALL GET_BMASK ;BX=INDEX*AX=MASK ON RETURN
- MOV SI,OFFSET FIRST_MASK
- MOV [SI],AX
- JMP SHORT MASK_COM1
- MASKS_FORW1:
- CALL GET_MASK ;BX=INDEX*AX=MASK ON RETURN
- MOV SI,OFFSET FIRST_MASK
- MOV [SI],AX
- MASK_COM1:
- ;
- ; NO MASK 2 USED, MASK 3 AND 4 SAME AS MASK 1
- ;
- MOV SI,OFFSET THIRD_MASK
- MOV [SI],AX
- MOV SI,OFFSET FOURTH_MASK
- MOV [SI],AX
- ;
- ; WRITE IN JUMP CODE OVER LODSW FOR SECOND SOURCE WORD GET
- ;
- MOV SI,OFFSET SKIP
- MOV AX,[SI]
- MOV SI,OFFSET PRECHRG_LOAD
- MOV [SI],AX
- JMP EPI_MASK
- PAGE
- MASKS_PRECH:
- ;
- ; BUILD MASKS FOR PRECHARGE OPERAION AND STORE THEM INTO
- ; THE COPY ROUTINE
- ;
- TEST HDIR,WORD PTR FORWARD
- JE FMASKP
- ;
- ; PRECHARGE MASK BUILD FOR BACKWARD COPY
- ;
- CALL GET_BMASK ;BX=INDEX*AX=MASK ON RETURN
- MOV DX,DI ; ROTATE MASK TO SSKEW-DSKEW*BITS_PIXE
- MOV CL,BYTE PTR LOG_BITS_PIX
- ROL DX,CL
- MOV CX,DX ; ADJUSTED SHIFT COUNT TO CL
- ROL AX,CL
- MOV SI,OFFSET FIRST_MASK
- MOV [SI],AX
- ;
- ; NOW GET SECOND/FOURTH MASK AND STORE IT
- ; DI HAS SKEW FACTOR
- ;
- PUSH BX
- MOV BX,DI
- CALL GET_BMASK ;BX=INDEX*AX=MASK ON RETURN
- POP BX
- MOV SI,OFFSET SECOND_MASK
- MOV [SI],AX
- MOV SI,OFFSET FOURTH_MASK
- MOV [SI],AX
- ;
- ; SAME FOR THIRD MASK
- ;
- PUSH BX
- MOV BX,DI
- DEC BX
- CALL GET_BMASK ;BX=INDEX*AX=MASK ON RETURN
- POP BX
- MOV SI,OFFSET THIRD_MASK
- MOV [SI],AX
- ;
- ; MAKE SURE LODSW AND IS RESTORED
- ;
- MOV SI,OFFSET LOAD_CODE
- MOV AL,[SI]
- MOV SI,OFFSET PRECHRG_LOAD
- MOV [SI],AL
- JMP EPI_MASK
- PAGE
- ;
- ; BUILD PRECHARGE MASKS FOR FORWARD COPY
- ;
- FMASKP:
- CALL GET_MASK ;BX=INDEX*AX=MASK ON RETURN
- MOV DX,DI ; ROTATE MASK TO SSKEW-DSKEW*BITS_PIXE
- MOV CL,BYTE PTR LOG_BITS_PIX
- ROL DX,CL
- MOV CX,DX ; ADJUSTED SHIFT COUNT TO CL
- ROL AX,CL
- MOV SI,OFFSET FIRST_MASK
- MOV [SI],AX
- ;
- ; NOW GET SECOND/FOURTH MASK AND STORE IT
- ; DI HAS SKEW FACTOR
- ;
- PUSH BX
- MOV BX,DI
- CALL GET_MASK ;BX=INDEX*AX=MASK ON RETURN
- POP BX
- MOV SI,OFFSET SECOND_MASK
- MOV [SI],AX
- MOV SI,OFFSET FOURTH_MASK
- MOV [SI],AX
- ;
- ; SAME FOR THIRD MASK
- ;
- PUSH BX
- MOV BX,DI
- INC BX
- CALL GET_MASK ;BX=INDEX*AX=MASK ON RETURN
- POP BX
- MOV SI,OFFSET THIRD_MASK
- MOV [SI],AX
- ;
- ; MAKE SURE LODSW AND IS RESTORED
- ;
- MOV SI,OFFSET LOAD_CODE
- MOV AL,[SI]
- MOV SI,OFFSET PRECHRG_LOAD
- MOV [SI],AL
- PAGE
- EPI_MASK:
- ;
- ; BUILD EPILOGUE MASK
- ;
- MOV DI,DSKEW_RIGHT
- ;
- ; RIGHT SKEW IS THE NUMBER OF PIXELS TO MODIFY
- ; SO JUST USE AS INDEX INTO BACK MASKS
- ;
- PUSH BX
- MOV BX,DI
- CALL GET_MASK ;BX=INDEX*AX=MASK ON RETURN
- POP BX
- MOV WORD PTR FIFTH_MASK,AX
- PAGE
- BUILD_ROTS:
- ; WRITE IN ROTATE CODES
- ;
- ; FIRST GET COUNT
- ;
- MOV CX,COUNT
- CMP BYTE PTR DIRECTION,BYTE PTR 0
- JE RIGHT_ROT
- MOV SI,OFFSET ROTATE_LEFT
- JMP SHORT WRITE_ROT1
- RIGHT_ROT:
- MOV SI,OFFSET ROTATE_RIGHT
- WRITE_ROT1:
- ADD SI,CX ; FORM INDEX INTO ROTATE CODE
- MOV AX,CS
- MOV ES,AX ; SET DESTINATION SEG=CODE
- MOV AX,SI ; SAVE INDEX INTO ROTATE CODE
- MOV DI,OFFSET FIRST_ROT ; SET DESTINATION INDEX
- STD ; SET DIRECTION FORWARD
- MOVSW ; COPY 1ST INSTRUCTION
- MOVSW ; COPY 2OND INSTRUCTION
- MOVSW ; COPY 3RD INSTRUCTION
- MOVSW ; COPY 4TH INSTRUCTION
- MOVSW ; COPY 5TH INSTRUCTION
- MOVSW ; COPY 6TH INSTRUCTION
- MOVSW ; COPY 7TH INSTRUCTION
- MOVSW ; COPY 8TH INSTRUCTION
- MOV DI,OFFSET SECOND_ROT ; SET DEST TO INNER LOOP
- MOV SI,AX ; RESET SOURCE TO TEMPLATE
- TEST PRECHRG,WORD PTR NO_PREC
- JNE DO_FIRST
- INC SI ;IF NO PRECHARGE DON'T OVER WRITE
- INC SI ; THE JUMP CODE
- JMP SHORT SKIP_FIRST
- DO_FIRST:
- MOVSW ; COPY 1ST INSTRUCTION
- SKIP_FIRST:
- MOVSW ; COPY 2OND INSTRUCTION
- MOVSW ; COPY 3RD INSTRUCTION
- MOVSW ; COPY 4TH INSTRUCTION
- MOVSW ; COPY 5TH INSTRUCTION
- MOVSW ; COPY 6TH INSTRUCTION
- MOVSW ; COPY 7TH INSTRUCTION
- MOVSW ; COPY 8TH INSTRUCTION
- MOV DI,OFFSET THIRD_ROT ; SET DEST TO INNER LOOP
- MOV SI,AX ; RESET SOURCE TO TEMPLATE
- MOVSW ; COPY 1ST INSTRUCTION
- MOVSW ; COPY 2OND INSTRUCTION
- MOVSW ; COPY 3RD INSTRUCTION
- MOVSW ; COPY 4TH INSTRUCTION
- MOVSW ; COPY 5TH INSTRUCTION
- MOVSW ; COPY 6TH INSTRUCTION
- MOVSW ; COPY 7TH INSTRUCTION
- MOVSW ; COPY 8TH INSTRUCTION
- PAGE
- MOV DI,OFFSET FOURTH_ROT ; SET DEST TO EPILOG
- MOV SI,AX ; RESET SOURCE TO TEMPLATE
- MOVSW ; COPY 1ST INSTRUCTION
- MOVSW ; COPY 2OND INSTRUCTION
- MOVSW ; COPY 3RD INSTRUCTION
- MOVSW ; COPY 4TH INSTRUCTION
- MOVSW ; COPY 5TH INSTRUCTION
- MOVSW ; COPY 6TH INSTRUCTION
- MOVSW ; COPY 7TH INSTRUCTION
- MOVSW ; COPY 8TH INSTRUCTION
- ;
- ;*********************************************************************
- ; *
- ; WRITE THE CODE TO PERFORM THE OPERATION REQUESTED INTO *
- ; THE PROLOG,EPILOG, AND INNER LOOP CODE OF THE HORZ COPY *
- ; *
- ; OPN_CODE*8 IS THE INDEX INTO THE TEMPLATE TABLES *
- ; *
- ; ASSUMES DS,ES POINT TO CODE SEG *
- ; *
- ;*********************************************************************
- ;
- MOV AL,OPN_CODE ; GET BITBLT OPERATION CODE
- XOR AH,AH ; CLEAR UPPER
- SAL AX,1 ; CODE TIMES 8
- SAL AX,1
- SAL AX,1
- MOV BP,AX ; SAVE OFFSET INTO BP
- ;
- ; FIRST DO INNER LOOP CODE
- ;
- CMP HDIR,0
- JNE BACKWARD_UN
- MOV SI,OFFSET OPN_LOOP_F ; LOCATION OF TEMPLATE
- JMP SHORT UN_IN_CMN ; COMMON INNER COPY
- BACKWARD_UN:
- MOV SI,OFFSET OPN_LOOP_B ; LOCATION OF TEMPLATE
- UN_IN_CMN:
- ADD SI,AX ; ADD IN INDEX
- MOV DI,OFFSET LOOP_OPN ; WHERE TO STORE TEMPLATE
- STD ; SET DIRECTION FORWARD
- MOVSW ; FIRST 2 BYTES OF OPERATION STREAM
- MOVSW ; BYTES 3-4
- MOVSW ; BYTES 5-6
- MOVSW ; BYTES 7-8
- ;
- ; THEN DO PROLOGUE OPERATION CODE
- ;
- MOV SI,OFFSET OPN_PRO_EPI ; LOCATION OF TEMPLATE
- ADD SI,BP ; ADD IN INDEX
- MOV BP,SI ; SAVE FOR 2OND COPY
- MOV DI,OFFSET PROLOG_OPN ; WHERE TO STORE TEMPLATE
- MOVSW ; FIRST 2 BYTES OF OPERATION STREAM
- MOVSW ; BYTES 3-4
- MOVSW ; BYTES 5-6
- MOVSW ; BYTES 7-8
- ;
- ; LASTLY DO EPILOGUE OPERATION CODE
- ;
- MOV SI,BP ; RESTORE TEMPLATE ORG
- MOV DI,OFFSET EPILOG_OPN ; WHERE TO STORE TEMPLATE
- MOVSW ; FIRST 2 BYTES OF OPERATION STREAM
- MOVSW ; BYTES 3-4
- MOVSW ; BYTES 5-6
- MOVSW ; BYTES 7-8
- MOV SAVE_SP,SP
- MOV SAVE_SS,SS
- .XLIST
- SUBTTL UNALIGNED COPY BITS ROUTINE-----VERTICAL LOOP
- .LIST
- PAGE +
- ;
- ;
- ;*********************************************************************
- ; *
- ; MAIN LOOP OF COPY BITS FOR UN-ALIGNED DATA *
- ; *
- ; *
- ; *
- ; *
- ;*********************************************************************
- COPYBITS_UN:
- XOR AX,AX
- CMP AX,HDIR
- JNE VERT_BACK_UN
- STD ; SET DIRECTION FORWARD, DELTA POS
- JMP SHORT V_LOADP_UN
- VERT_BACK_UN:
- CLD ; SET DIRECTION BACKWARD, DELTA NEG
- V_LOADP_UN:
- LES SI,CURR_PTR_S ; SET UP ALL PTRS XCEPT DS
- MOV AX,ES
- LES DI,CURR_PTR_D
- CLI ; DISABLE INTERRUPTS
- MOV SP,AX
- PAGE
- ;
- ;*********************************************************************
- ; *
- ; INNER PART OF VERT LOOP. THIS CODE RUNS BLIND BECAUSE THE *
- ; MAIN BITBLT CODE DETERMINED HOW MANY SCAN LINES CAN BE RUN *
- ; BEFORE THE VIDEO MUST BE TURNED ON. (IE HOW MANY WORDS CAN BE *
- ; COPIED IN 1/60 SEC) *
- ; *
- ;*********************************************************************
- DUMMY EQU 0
- SELF_MASK1 EQU DUMMY
- SELF_MASK2 EQU DUMMY
- SELF_MASK3 EQU DUMMY
- SELF_MASK4 EQU DUMMY
- SELF_MASK5 EQU DUMMY
- SELF_HWC EQU DUMMY
- H_MASK_END EQU DUMMY
- VERT_LOOP:
- XOR BX,BX
- MOV BL,HTONE_INDX ; GET HALF TONE INDEX
- AND BL,HTONE_MOD ; USE MODULO ARITHMETIC
- MOV BP,HTONE_VEC[BX] ; GET HALF TONE VALUE
- INC BL ; TO NEXT HALF TONE
- MOV HTONE_INDX,BL
- MOV AX,SP
- MOV DS,AX ; DS ADDRESSIBILTY TO SOURCE
- .XLIST
- SUBTTL UNALIGNED HORIZONTAL COPY ROUTINE---PROLOGUE
- .LIST
- PAGE +
- ;
- ;*********************************************************************
- ; *
- ; ASSUMES: DS,SI POINT TO SOURCE WORD *
- ; ES,DI POINT TO DEST WORD *
- ; BP HAS HALFTONE MASK *
- ; *
- ; DESTROYS: AX,BX,CX,DX,SS,SI,DI,SP *
- ; *
- ;*********************************************************************
- ; HORIZONTAL COPY LOOP OF BITBLIT. A GREAT DEAL OF THIS CODE *
- ; IS MODIFIED IN THE MAIN SETUP PORTION OF BITBLT. THIS *
- ; MAY SEEM UGLY (AND IT IS), BUT THE TIME SAVINGS IT *
- ; ACHIEVES IS WELL WORTH THE UGLINESS. THIS PARTICULAR *
- ; COPY LOOP IS EXECUTED ONLY IS THOSE CASES WHERE THE *
- ; OFFSET OF PIXELS WITHIN A WORD IS NOT THE SAME IN THE *
- ; SOURCE BITMAP AND THE DESTINATION BITMAP. THIS DOES NOT INCLUDE *
- ; THE FOLLOWING CASES: *
- ; CONSTANT TO DESTINATION IE, CLEAR, ALLONES, OR HALFTONE/COLOR *
- ;*********************************************************************
- ;
- ;*********************************************************************
- ; *
- ; SETUP CODE FIRST. SETUP FOR FIRST PARTIAL WORD COPY *
- ; *
- ;*********************************************************************
- ;
- ; GET THE FIRST SOURCE WORD AND ROTATE IT INTO POSITION
- ;
-
- LODSW ; AX<-- DS:[SI],SI<-- SI+/-2
- EVEN
- H_SELF1:
- ROR AX,1 ; BITBLT MAIN WILL RE-WRITE
- ROR AX,1 ; BITBLT MAIN WILL RE-WRITE
- ROR AX,1 ; BITBLT MAIN WILL RE-WRITE
- ROR AX,1 ; BITBLT MAIN WILL RE-WRITE
- ROR AX,1 ; BITBLT MAIN WILL RE-WRITE
- ROR AX,1 ; BITBLT MAIN WILL RE-WRITE
- ROR AX,1 ; BITBLT MAIN WILL RE-WRITE
- ROR AX,1 ; BITBLT MAIN WILL RE-WRITE
- PAGE
- ;
- ; NOW MASK OFF THE STUFF NEEDED FROM SOURCE WORD 1
- ;
- NOP ; PUT OPERAND ON EVEN
- H_SELF2:
- MOV CX,WORD PTR SELF_MASK1
- MOV SS,AX ; WE DO IT THIS WAY BECAUSE
- AND AX,CX ; BITBLT MAIN MAY DECIDE TO USE
- MOV BX,AX ; ONLY ONE WORD (NO PRECHARGE)
- ;
- ; HAD TO PUT THE JUMP IN HERE BECAUSE MASM WILL NOT ALLOW
- ; AN ORG TO A RELATIVE ADDRESS
- ;
- ; THE NEXT 3 BYTES MAY BE ONE OF TWO INSTRUCTION STREAMS
- ; THE JUMP (CODED INLINE)
- ; A LODSW AND ROR(ROL),1
- ;
- NOP ; PUT FIRST BYTE OF JUMP ON ODD
- H_SELF3: ; GET SOURCE WORD 2 AND ROTATE
- SKIP_CODE:
- JMP SHORT NO_PRECHARG ; BITBLT MAIN WILL REWRITE
- NOP
- ROR AX,1 ; BITBLT MAIN WILL RE-WRITE
- ROR AX,1 ; BITBLT MAIN WILL RE-WRITE
- ROR AX,1 ; BITBLT MAIN WILL RE-WRITE
- ROR AX,1 ; BITBLT MAIN WILL RE-WRITE
- ROR AX,1 ; BITBLT MAIN WILL RE-WRITE
- ROR AX,1 ; BITBLT MAIN WILL RE-WRITE
- ROR AX,1 ; BITBLT MAIN WILL RE-WRITE
- MOV SS,AX ; WORD 2 NEEDED TO PRECHARGE LOOP
- NOP ; PUT OPERAND ON EVEN
- H_SELF4:
- MOV CX,WORD PTR SELF_MASK2
- AND AX,CX ; MASK PIXELS IN SOURCE WORD 2
- OR BX,AX ; SWORD1|SWORD2 NOW ALIGNED WITH DEST
- NO_PRECHARG:
- AND BX,BP ; AND IN HALFTONE/COLOR
- MOV AX,ES:[DI] ; GET DESTINATION WORD
- H_SELF5:
- MOV CX,WORD PTR SELF_MASK3
- MOV DX,AX ; SPLIT DEST WORD INTO 2 PARTS
- AND AX,CX ; 1-THE PART TO BE MODIFIED
- NOT CX
- AND DX,CX ; 2- THE PART TO NOT MODIFY
- H_SELF7:
- NOT AX ; BITBLT WILL REWRITE \
- NOT BX ; BITBLT WILL REWRITE * OPERATION
- OR AX,BX ; BITBLT WILL REWRITE /
- NOP ; BITBLT WILL REWRITE
- NOP ; BITBLT WILL REWRITE
- OR AX,DX ; MERGE DEST TOGETHER
- STOSW ; RESULT OF MERGE-->ES:[DI], DI-->DI+2
- XOR CX,CX ; PUT H WORD COUNT INTO CX
- H_SELF8:
- MOV CX,WORD PTR 0 ; NUMBER OF WORDS WRITTEN HERE
- ;
- ; HWC=N-1 IF NO PRECHARGE N-2 IF PRECHARGE
- ;
- AND CL,CL
- JZ H_TERMIN
- H_SELF9:
- MOV BX,WORD PTR SELF_MASK4 ; MASK TO BE USED FOR LOOP R
- .XLIST
- SUBTTL UNALIGNED HORIZONTAL COPY ROUTINE---INNER LOOP
- .LIST
- PAGE +
- ;*********************************************************************
- ; *
- ; WAY WAY INNER LOOP OF BITBLT (EXECUTED MANY MANY TIMES) *
- ; *
- ;*********************************************************************
- EVEN
- NOP ; MAKE LODSW ODD REST EVEN
- HORZW_LOOP: ; ON ENTEY DX=PREV PART
- LODSW
- H_SELF10: ROR AX,1 ; BITBLT MAIN WILL RE-WRITE
- ROR AX,1 ; BITBLT MAIN WILL RE-WRITE
- ROR AX,1 ; BITBLT MAIN WILL RE-WRITE
- ROR AX,1 ; BITBLT MAIN WILL RE-WRITE
- ROR AX,1 ; BITBLT MAIN WILL RE-WRITE
- ROR AX,1 ; BITBLT MAIN WILL RE-WRITE
- ROR AX,1 ; BITBLT MAIN WILL RE-WRITE
- ROR AX,1 ; BITBLT MAIN WILL RE-WRITE
- MOV SS,AX ; SAVE THIS WORD
- AND AX,BX ; MASK OFF NUMBER OF BITS THIS WORD
- NOT BX ; COMPLEMENT MASK FOR PREV WORD
- AND DX,BX ; MASK OFF NUMBER OF BITS PREV WORD
- NOT BX ; RESTORE MASK
- OR AX,DX ; AX NOW HAS WORD FOR DESTINATION
- AND AX,BP ; AND IN HALFTONE MASK
- H_SELF11:
- NOP ; THIS BLOCK REWRITTEN BY BITBLT MAIN
- NOP ; SAVES HAVING TO WRITE 16 LOOPS
- NOP ; EACH WITH ITS OWN MERGE FUNCTION
- NOP ;
- NOP ; DOING A VECTOR JUMP AND A EXIT JUMP
- NOP ; TAKES WAY TOO MUCH TIME APPROX 31 CLOCKS
- NOP ;
- NOP ;
- MOV DX,SS ; SETUP DX FOR NEXT
- LOOP HORZW_LOOP
- .XLIST
- SUBTTL UNALIGNED HORIZONTAL COPY ROUTINE---EPILOGUE
- .LIST
- PAGE +
- ;
- ;*********************************************************************
- ; *
- ; NOW DO LAST WORD. THIS IS THE SAME A LOOP, JUST MASK OFF *
- ; SOURCE ONE LAST TIME SO WE DON'T MOVE BEYOND THE DESTINATION IN X *
- ; *
- ; *
- ;*********************************************************************
- ;
- H_TERMIN:
- LODSW
- EVEN
- H_SELF12:
- ROR AX,1 ; BITBLT MAIN WILL RE-WRITE
- ROR AX,1 ; BITBLT MAIN WILL RE-WRITE
- ROR AX,1 ; BITBLT MAIN WILL RE-WRITE
- ROR AX,1 ; BITBLT MAIN WILL RE-WRITE
- ROR AX,1 ; BITBLT MAIN WILL RE-WRITE
- ROR AX,1 ; BITBLT MAIN WILL RE-WRITE
- ROR AX,1 ; BITBLT MAIN WILL RE-WRITE
- ROR AX,1 ; BITBLT MAIN WILL RE-WRITE
- AND AX,BX ; MASK OFF NUMBER OF BITS THIS WORD
- NOT BX ; COMPLEMENT MASK FOR PREV WORD
- AND DX,BX ; MASK OFF NUMBER OF BITS PREV WORD
- OR DX,AX ; DX NOW HAS WORD FOR DESTINATION
- AND DX,BP ; AND IN HALFTONE MASK
- NOP ; PUT OPERAND ON EVEN
- H_SELF13:
- MOV CX,WORD PTR H_MASK_END
- MOV BX,DX ; PUT SOURCE INTO BX SO REWRITE'S OK
- AND BX,CX
- MOV AX,ES:[DI]
- NOP ; PUT REST EVEN
- MOV DX,AX ; SPLIT DEST WORD INTO 2 PARTS
- AND AX,CX ; 1- THE PART TO BE MODIFIED
- NOT CX ; MASK OFF STUFF TO KEEP AT DEST
- AND DX,CX ; 2- THE INVARIANT PART
- ;
- ; HERE AX HAS WORD TO BE OP'D FROM DEST AND BX AND SOURCE TO OP
- ;
- H_SELF14:
- NOT BX ; THIS BLOCK REWRITTEN BY BITBLT MAIN
- NOT AX ; SAVES HAVING TO WRITE 16 LOOPS
- OR AX,BX ; EACH WITH ITS OWN MERGE FUNCTION
- OR AX,DX ; MERGE DEST PARTS TOGETHER
- STOSW
- .XLIST
- SUBTTL BOTTOM PART OF VERTICAL LOOP
- .LIST
- PAGE +
- ;
- ;*********************************************************************
- ; *
- ; TERMINATING PORTION OF VERT LOOP. CURRENT SCAN LINE IS COMPLETE *
- ; *
- ;*********************************************************************
- MOV AX,DS ; RESTORE ADDRESSIBILTY TO DATA
- MOV SP,AX ; SAVE DS IN SP
- MOV AX,CS
- MOV DS,AX
- ADD SI,DELTA_S ; ADJUST POINTER FOR SOURCE
- ADD DI,DELTA_D ; ADJUST POINTER FOR DESTINATION
- DEC V_WORD_CNT ; DONE YET?
- JZ EXIT_V_UN ; YES DO ANOTHER V LOOP
- JMP VERT_LOOP ; NO, DO ANOTHER SCAN LINE
- EXIT_V_UN:
- MOV SS,SAVE_SS
- MOV SP,SAVE_SP
- STI ; INTERRUPTS OFF LONG ENOUGH
- RET
- .XLIST
- SUBTTL UNALIGNED HORIZ COPY SELF MODIFY EQUATES
- .LIST
- PAGE +
- ;
- ;*********************************************************************
- ; *
- ; THE FOLLOWING ARE EQUATES INTO THE UGLY HORIZONTAL CODE *
- ; TO LOCATE THE CODE TO MODIFY *
- ; *
- ;*********************************************************************
- ;
- FIRST_ROT EQU H_SELF1 ; PROLOGUE 1ST ROTATE
- PRECHRG_LOAD EQU H_SELF3 ; PRECHARGE LOAD
- SECOND_ROT EQU H_SELF3+1 ; PROLOGUE 2OND ROTATE
- THIRD_ROT EQU H_SELF10 ; INNER LOOP ROTATE
- FOURTH_ROT EQU H_SELF12 ; EPILOGUE ROTATE
- FIRST_MASK EQU H_SELF2+1 ; WHERE TO STORE FIRST MASK
- SECOND_MASK EQU H_SELF4+1 ; WHERE TO STORE SECOND MASK
- THIRD_MASK EQU H_SELF5+1
- FOURTH_MASK EQU H_SELF9+1
- FIFTH_MASK EQU H_SELF13+1 ; EPILOGUE MASK
- H_WORD_COUNT EQU H_SELF8+1 ; WHERE TO STORE THE H_COUNT
- PROLOG_OPN EQU H_SELF7 ;WHERE TO WRITE THE OPERATION COD
- LOOP_OPN EQU H_SELF11
- EPILOG_OPN EQU H_SELF14
- COPY_NALIGN ENDP
- .XLIST
- SUBTTL ALIGNED HORIZONTAL COPY ROUTINE
- .LIST
- PAGE +
- COPY_ALIGN PROC NEAR
- MOV SAVE_SS,SS ; SAVE SS
- MOV SAVE_SP,SP ; SAVE SP
- ;
- ;*********************************************************************
- ; *
- ; GET MASKS FOR START AND END IN ALIGNED COPY *
- ; *
- ;*********************************************************************
- ;
- XOR AX,AX ; CHECK IF FORWARD/BACKWARD COPY
- CMP AX,HDIR
- JNE BACKMASK_AL
- MOV BX,SSKEW_LEFT ; FORWARD COPY. GET SOURCE SKEW
- XOR BH,BH
- CALL GET_MASK
- MOV ALIGN_PRMASK,AX ; SAVE PROLOGUE MASK
- MOV BX,SSKEW_RIGHT ; GET SKEW AT RIGHT SIDE
- XOR BH,BH ; USE AS INDEX FOR EPILOGUE MASK
- CALL GET_BMASK
- MOV ALIGN_EPMASK,AX
- JMP SHORT COPYBITS_AL
- BACKMASK_AL:
- MOV BX,SSKEW_LEFT ; IF BACKWARD CHK_OVLAP HAS
- XOR BH,BH ; SWAPPED LEFT AND RIGHT
- CALL GET_BMASK
- NOT AX
- MOV ALIGN_PRMASK,AX
- MOV BX,SSKEW_RIGHT
- XOR BH,BH
- CALL GET_MASK
- MOV ALIGN_EPMASK,AX
- PAGE
- ;
- ;*********************************************************************
- ; *
- ; COPY IN OPERATION CODE *
- ; *
- ;*********************************************************************
- ;
- XOR BX,BX ; CLEAR BX
- MOV BL,OPN_CODE ; GET INDEX TO OPERATION
- SAL BX,1 ; TEMPLATES TIMES 8
- SAL BX,1
- SAL BX,1
- MOV SI,OFFSET OPN_PRO_EPI ; GET ADDRESS FOR TEMPLATE
- ADD SI,BX ; ADD IN INDEX
- MOV BP,SI ; SAVE IT IN BP
- MOV DI,OFFSET ALIGN_PROP ; GET TARGET FOR 1ST COPY
- MOV AX,CS ; SET UP ES FOR CS
- MOV ES,AX ; (DS ALREADY IS THERE)
- STD ; FORWARD COPY
- MOVSW ;
- MOVSW ; COPY OPERATION CODE
- MOVSW
- MOVSW
- MOV SI,BP ; BACK TO START OF TEMPLATE
- MOV DI,OFFSET ALIGN_INOP ; NEW TARGET
- MOVSW
- MOVSW ; COPY OPERATION CODE
- MOVSW
- MOVSW
- MOV SI,BP ; BACK TO START OF TEMPLATE
- MOV DI,OFFSET ALIGN_INOP ; NEW TARGET
- MOVSW
- MOVSW ; COPY OPERATION CODE
- MOVSW
- MOVSW
- PAGE
- ;
- ;*********************************************************************
- ; *
- ; COPY BITS FOR THOSE CASES WHERE THE DESTINATION AND SOURCE *
- ; HAPPEN TO BE ALIGNED *
- ; *
- ;*********************************************************************
- ;
- COPYBITS_AL:
- XOR AX,AX
- CMP AX,HDIR
- JB VERT_BACK_AL
- STD ; FORWARD COPY, DET DIRECTION
- JMP SHORT V_LOADP_AL
- VERT_BACK_AL:
- CLD ; BACKWARD COPY, CLEAR DIRECTION
- V_LOADP_AL:
- LES SI,CURR_PTR_S ; LOAD SOURCE AND DEST POINTERS
- MOV AX,ES
- LES DI,CURR_PTR_D
- CLI ; DISABLE INTERRUPTS
- MOV SS,AX
- PAGE
- ALIGN_VERT:
- XOR BX,BX
- MOV BL,HTONE_INDX ; GET THE HALFTONE WORD
- AND BL,HTONE_MOD ; FOR THIS SCAN LINE
- MOV BP,HTONE_VEC[BX]
- INC BX
- MOV HTONE_INDX,BL
- MOV AX,SS
- MOV DS,AX
- PAGE
- ;*********************************************************************
- ; *
- ; ALIGNED HORIZONTAL COPY ROUTINE *
- ; *
- ; *
- ; ASSUMES DS,SI==>SOURCE BITMAP *
- ; ES,DI==>DEST BITMAP *
- ; BP = HALFTONE MASK *
- ; *
- ; *
- ;*********************************************************************
- ;
- ;
- ; PROLOGUE OPERATION
- ;
- LODSW ; GET SOURCE 1ST WORD
- MOV DX,CS:ALIGN_PRMASK
- AND AX,DX ; MASK OFF 1ST WORD DATA TO KEEP
- AND AX,BP ; PUT IN HALF TONE
- MOV BX,ES:[DI] ; GET DESTINATION 1ST WORD
- MOV CX,BX ; PUT PORTION OF DEST NOT TO BE
- NOT DX ; MODIFIED INTO CX
- AND CX,DX
- NOT DX ; BRING BACK MASK
- AND BX,DX ; MASK OFF DATA TO BE MODIFIED
- EVEN
- ALIGN_PROP:
- NOP ; THESE 8 BYTES WILL BE REWRITTEN
- NOP ; WITH THE APPROPRIATE OPERATION
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- OR AX,CX ; MERGE MODIFIED WITH CONSTANT
- STOSW ; PUT DESTINATION BACK
- MOV CX,CS:NWORDS
- PAGE
- ALIGN_INNER:
- LODSW ; GET NEXT SOURCE WORD
- MOV BX,ES:[DI] ; GET NEXT DEST WORD
- AND AX,BP ; AND IN HALFTONE
- EVEN
- ALIGN_INOP:
- NOP ; OPERATION WILL BE WRITTEN IN
- NOP ;
- NOP ;
- NOP ;
- NOP ;
- NOP ;
- NOP ;
- NOP ; THESE 8 BYTES
- LOOP ALIGN_INNER
- PAGE
- ;
- ; EPILOG OPERATION
- ;
- LODSW ; GET SOURCE 1ST WORD
- MOV DX,CS:ALIGN_EPMASK
- AND AX,DX ; MASK OFF 1ST WORD DATA TO KEEP
- AND AX,BP ; PUT IN HALF TONE
- MOV BX,ES:[DI] ; GET DESTINATION 1ST WORD
- MOV CX,BX ; PUT PORTION OF DEST NOT TO BE
- NOT DX ; MODIFIED INTO CX
- AND CX,DX
- NOT DX ; BRING BACK MASK
- AND BX,DX ; MASK OFF DATA TO BE MODIFIED
- EVEN
- ALIGN_EPOP:
- NOP ; THESE 8 BYTES WILL BE REWRITTEN
- NOP ; WITH THE APPROPRIATE OPERATION
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- OR AX,CX ; MERGE MODIFIED WITH CONSTANT
- STOSW ; PUT DESTINATION BACK
- PAGE
- ;
- ; LOWER PORTION OF VERT LOOP
- ;
- MOV AX,DS
- MOV SS,AX ; SAVE OLD SEG TO SOURCE
- MOV AX,CS
- MOV DS,AX ; RESTORE ADDRESSIBILTY TO CS
- ADD SI,DELTA_S
- ADD DI,DELTA_D
- DEC V_WORD_CNT ; ANOTHER H SCAN
- JZ DONE_VERT ; YES, GO DO IT
- JMP ALIGN_VERT
- DONE_VERT:
- MOV SS,SAVE_SS
- MOV SP,SAVE_SP
- STI ; ENABLE INTERRUPTS
- RET
- COPY_ALIGN ENDP
- .XLIST
- SUBTTL FAST COPY ROUTINE----MAIN PROC
- .LIST
- PAGE +
- COPY_FAST PROC NEAR
- MOV SAVE_SS,SS ; SAVE SS
- MOV SAVE_SP,SP ; SAVE SP
- MOV AL,OPN_CODE
- CMP AL,OP_D
- JNE FAST_ND
- CALL FASTBITS_D
- RET
- FAST_ND:
- CMP AL,OP_ND
- JNE FAST_1
- CALL FASTBITS_ND
- RET
- FAST_1:
- CMP AL,OP_ONES
- CALL FASTBITS_1
- RET
- CALL FASTBITS_0
- RET
- .XLIST
- SUBTTL FAST COPY ROUTINE-----OPCODE OF D
- .LIST
- PAGE +
- ;
- ;*********************************************************************
- ; *
- ; COPY BITS FOR THE CASE OF D OPERATION CODE *
- ; *
- ;*********************************************************************
- ;
- FASTBITS_D:
- MOV SI,V_WORD_CNT
- STD ; FORWARD COPY, DET DIRECTION
- LES DI,CURR_PTR_D
- CLI ; DISABLE INTERRUPTS
- MOV BX,DSKEW_LEFT ; GET PROLOGUE MASK
- CALL GET_MASK
- MOV DX,AX
- MOV BX,DSKEW_RIGHT ; GET EPILOGUE MASK
- CALL GET_BMASK
- MOV SP,NWORDS
- MOV SS,AX
- PAGE
- D_VERT:
- XOR BX,BX
- MOV BL,HTONE_INDX ; GET THE HALFTONE WORD
- AND BL,HTONE_MOD ; FOR THIS SCAN LINE
- MOV BP,HTONE_VEC[BX]
- INC BX
- MOV HTONE_INDX,BL
- MOV CX,SP ; HORZ COUNT
- PAGE
- ;*********************************************************************
- ; *
- ; FAST HORIZONTAL COPY ROUTINE *
- ; *
- ; *
- ; ES,DI==>DEST BITMAP *
- ; BP = HALFTONE MASK *
- ; DX = PROLOGUE MASK *
- ; SS = EPILOGUE MASK *
- ; SP = HORZ COUNT *
- ; *
- ; *
- ;*********************************************************************
- ;
- ;
- ; PROLOGUE OPERATION
- ;
- MOV AX,ES:[DI] ; GET SOURCE 1ST WORD
- MOV BX,AX
- AND AX,DX ; MASK OFF 1ST WORD DATA TO KEEP
- NOT DX ; MASK OFF STUFF TO KEEP
- AND BX,DX
- AND AX,BP ; PUT IN HALF TONE
- OR AX,BX ; MERGE BACK
- MOV ES:[DI],AX ; PUT RESULT TO DESTINATION
- INC DI
- INC DI
- D_INNER:
- AND ES:[DI],BP ; AND IN HALFTONE
- INC DI
- INC DI
- LOOP D_INNER
- ;
- ; EPILOG OPERATION
- ;
- MOV AX,ES;[DI] ; GET DEST LAST WORD
- MOV DX,SS ; EPILOGUE MASK IN SS
- MOV BX,AX ; BX WILL HAVE PART TO RETAIN
- AND AX,DX ; MASK OFF 1ST WORD DATA TO KEEP
- NOT DX
- AND BX,DX
- AND AX,BP ; PUT IN HALF TONE
- OR AX,BX ; MERGE TOGETHER
- MOV ES:[DI],AX
- INC DI
- INC DI
- PAGE
- ;
- ; LOWER PORTION OF VERT LOOP
- ;
- ADD DI,DELTA_D
- DEC SI ; ANOTHER H SCAN
- JNZ D_VERT
- ;
- MOV SS,SAVE_SS
- MOV SP,SAVE_SP
- STI ; ENABLE INTERRUPTS
- RET
- .XLIST
- SUBTTL FAST COPY ROUTINE-----OPCODE OF ~D
- .LIST
- PAGE +
- ;
- ;*********************************************************************
- ; *
- ; COPY BITS FOR THE CASE OF ~D OPERATION CODE *
- ; *
- ;*********************************************************************
- ;
- FASTBITS_ND:
- MOV SI,V_WORD_CNT ; STORE THE NUMBER OF LINES TO
- STD ; FORWARD COPY, DET DIRECTION
- LES DI,CURR_PTR_D
- CLI ; DISABLE INTERRUPTS
- XOR BH,BH
- MOV BX,DSKEW_LEFT ; GET PROLOGUE MASK
- CALL GET_MASK
- MOV DX,AX
- MOV BX,DSKEW_RIGHT ; GET EPILOGUE MASK
- CALL GET_BMASK
- MOV SP,NWORDS
- MOV SS,AX
- PAGE
- ND_VERT:
- XOR BX,BX
- MOV BL,HTONE_INDX ; GET THE HALFTONE WORD
- AND BL,HTONE_MOD ; FOR THIS SCAN LINE
- MOV BP,HTONE_VEC[BX]
- INC BX
- MOV HTONE_INDX,BL
- MOV CX,SP ; HORZ COUNT
- PAGE
- ;*********************************************************************
- ; *
- ; FAST HORIZONTAL COPY ROUTINE *
- ; *
- ; *
- ; ES,DI==>DEST BITMAP *
- ; BP = HALFTONE MASK *
- ; DX = PROLOGUE MASK *
- ; SS = EPILOGUE MASK *
- ; SP = HORZ COUNT *
- ; SI = VERT COUNT *
- ; *
- ;*********************************************************************
- ;
- ;
- ; PROLOGUE OPERATION
- ;
- MOV AX,ES:[DI] ; GET SOURCE 1ST WORD
- MOV BX,AX
- AND AX,DX ; MASK OFF 1ST WORD DATA TO KEEP
- NOT DX ; MASK OFF STUFF TO KEEP
- AND BX,DX
- NOT AX
- AND AX,BP ; PUT IN HALF TONE
- OR AX,BX ; MERGE BACK
- MOV ES:[DI],AX ; PUT RESULT TO DESTINATION
- INC DI
- INC DI
- ND_INNER:
- MOV AX,ES:[DI] ; GET DEST WORD
- NOT AX
- AND AX,BP
- MOV ES:[DI],AX ; STORE DEST WORD
- INC DI
- INC DI
- LOOP ND_INNER
- ;
- ; EPILOG OPERATION
- ;
- MOV AX,ES;[DI] ; GET DEST LAST WORD
- MOV DX,SS ; EPILOGUE MASK IN SS
- MOV BX,AX ; BX WILL HAVE PART TO RETAIN
- AND AX,DX ; MASK OFF 1ST WORD DATA TO KEEP
- NOT DX
- AND BX,DX
- NOT AX
- AND AX,BP ; PUT IN HALF TONE
- OR AX,BX ; MERGE TOGETHER
- MOV ES:[DI],AX
- INC DI
- INC DI
- PAGE
- ;
- ; LOWER PORTION OF VERT LOOP
- ;
- ADD DI,DELTA_D
- DEC SI ; ANOTHER H SCAN
- JNZ ND_VERT
- ;
- MOV SS,SAVE_SS
- MOV SP,SAVE_SP
- STI ; ENABLE INTERRUPTS
- RET
- .XLIST
- SUBTTL FAST COPY ROUTINE-----OPCODE OF ALLONES
- .LIST
- PAGE +
- ;
- ;*********************************************************************
- ; *
- ; COPY BITS FOR THE CASE OF ONES AND ZEROES OPCODE *
- ; *
- ;*********************************************************************
- ;
- FASTBITS_1:
- MOV SI,V_WORD_CNT ; STORE THE NUMBER OF LINES TO
- LES DI,CURR_PTR_D
- CLI ; DISABLE INTERRUPTS
- XOR BX,BX
- MOV BX,DSKEW_LEFT ; GET PROLOGUE MASK
- CALL GET_MASK
- MOV DX,AX
- MOV BX,DSKEW_RIGHT ; GET EPILOGUE MASK
- CALL GET_BMASK
- MOV SS,AX
- MOV SP,NWORDS
- PAGE
- VERT_1:
- XOR BX,BX
- MOV BL,HTONE_INDX ; GET THE HALFTONE WORD
- AND BL,HTONE_MOD ; FOR THIS SCAN LINE
- MOV BP,HTONE_VEC[BX]
- INC BX
- MOV HTONE_INDX,BL
- MOV CX,SP ; HORZ COUNT
- PAGE
- ;*********************************************************************
- ; *
- ; FAST HORIZONTAL COPY ROUTINE *
- ; *
- ; *
- ; ES,DI==>DEST BITMAP *
- ; BP = HALFTONE MASK *
- ; DX = PROLOGUE MASK *
- ; SS = EPILOGUE MASK *
- ; SP = HORZ COUNT *
- ; SI = VERT COUNT *
- ; *
- ;*********************************************************************
- ;
- ;
- ; PROLOGUE OPERATION
- ;
- MOV AX,ES:[DI] ; GET SOURCE 1ST WORD
- MOV BX,AX
- AND AX,DX ; MASK OFF 1ST WORD DATA TO KEEP
- NOT DX ; MASK OFF STUFF TO KEEP
- AND BX,DX
- AND AX,BP ; PUT IN HALF TONE
- OR AX,BX ; MERGE BACK
- MOV ES:[DI],AX ; PUT RESULT TO DESTINATION
- INC DI
- INC DI
- INNER_1:
- AND ES:[DI],BP ; BP ANREADY AND'D WITH 0'S/1'S
- INC DI
- INC DI
- LOOP INNER_1
- ;
- ; EPILOG OPERATION
- ;
- MOV AX,ES:[DI] ; GET DEST LAST WORD
- MOV DX,SS ; EPILOGUE MASK IN SS
- MOV BX,AX ; BX WILL HAVE PART TO RETAIN
- AND AX,DX ; MASK OFF 1ST WORD DATA TO KEEP
- NOT DX
- AND BX,DX
- AND AX,BP ; PUT IN HALF TONE
- OR AX,BX ; MERGE TOGETHER
- MOV ES:[DI],AX
- INC DI
- INC DI
- PAGE
- ;
- ; LOWER PORTION OF VERT LOOP
- ;
- ADD DI,DELTA_D
- DEC SI ; ANOTHER H SCAN
- JNZ VERT_1
- ;
- MOV SS,SAVE_SS
- MOV SP,SAVE_SP
- STI ; ENABLE INTERRUPTS
- RET
- .XLIST
- SUBTTL FAST COPY ROUTINE-----OPCODE OF ALLZEROES
- .LIST
- PAGE +
- ;
- ;*********************************************************************
- ; *
- ; COPY BITS FOR THE CASE OF ONES AND ZEROES OPCODE *
- ; *
- ;*********************************************************************
- ;
- FASTBITS_0:
- MOV SI,V_WORD_CNT ; STORE THE NUMBER OF LINES TO
- LES DI,CURR_PTR_D
- CLI ; DISABLE INTERRUPTS
- XOR BX,BX
- MOV BX,DSKEW_LEFT ; GET PROLOGUE MASK
- CALL GET_MASK
- MOV DX,AX
- MOV BX,DSKEW_RIGHT ; GET EPILOGUE MASK
- CALL GET_BMASK
- MOV SS,AX
- MOV SP,NWORDS
- XOR BP,BP ; CLEAR DESTINATION
- VERT_0:
- MOV CX,SP ; HORZ COUNT
- PAGE
- ;*********************************************************************
- ; *
- ; FAST HORIZONTAL COPY ROUTINE *
- ; *
- ; *
- ; ES,DI==>DEST BITMAP *
- ; BP = HALFTONE MASK *
- ; DX = PROLOGUE MASK *
- ; SS = EPILOGUE MASK *
- ; SP = HORZ COUNT *
- ; SI = VERT COUNT *
- ; *
- ;*********************************************************************
- ;
- ;
- ; PROLOGUE OPERATION
- ;
- MOV AX,ES:[DI] ; GET SOURCE 1ST WORD
- MOV BX,AX
- AND AX,DX ; MASK OFF 1ST WORD DATA TO KEEP
- NOT DX ; MASK OFF STUFF TO KEEP
- AND BX,DX
- AND AX,BP ; PUT IN HALF TONE
- OR AX,BX ; MERGE BACK
- MOV ES:[DI],AX ; PUT RESULT TO DESTINATION
- INC DI
- INC DI
- INNER_0:
- AND ES:[DI],BP ; BP ANREADY AND'D WITH 0'S/1'S
- INC DI
- INC DI
- LOOP INNER_0
- ;
- ; EPILOG OPERATION
- ;
- MOV AX,ES:[DI] ; GET DEST LAST WORD
- MOV DX,SS ; EPILOGUE MASK IN SS
- MOV BX,AX ; BX WILL HAVE PART TO RETAIN
- AND AX,DX ; MASK OFF 1ST WORD DATA TO KEEP
- NOT DX
- AND BX,DX
- AND AX,BP ; PUT IN HALF TONE
- OR AX,BX ; MERGE TOGETHER
- MOV ES:[DI],AX
- INC DI
- INC DI
- PAGE
- ;
- ; LOWER PORTION OF VERT LOOP
- ;
- ADD DI,DELTA_D
- DEC SI ; ANOTHER H SCAN
- JNZ VERT_0
- ;
- MOV SS,SAVE_SS
- MOV SP,SAVE_SP
- STI ; ENABLE INTERRUPTS
- RET
- COPY_FAST ENDP
- .XLIST
- SUBTTL CALCULATE SCAN LINES PROCESSED IN 1/60 SEC
- .LIST
- PAGE +
- PAGE +
- HTONE_GET PROC NEAR
- HTONE_GET ENDP
- COPY_DISPLAY PROC NEAR
- COPY_DISPLAY ENDP
- BITBLT_INIT PROC NEAR
- BITBLT_INIT ENDP
- BITBLT ENDP
- ?BITBLT ENDS
- END